package gosend

import (
	"encoding/json"
	"errors"
	"log/slog"
	"net/http"

	"gitee.com/gxcc/go-utils/utils"
)

// gosend 下单 详见https://docs.google.com/document/d/1kbTfByn_BZ0ONmg7Amund_tBDmizV-c4eEdmUz14lws/edit?ts=5d074222#

type Request struct {
	PaymentType        int     `json:"paymentType"`
	DeviceToken        string  `json:"deviceToken"`
	CollectionLocation string  `json:"collection_location"`
	ShipmentMethod     string  `json:"shipment_method"`
	Routes             []Route `json:"routes"`
}

type Route struct {
	OriginName              string `json:"originName"`
	OriginNote              string `json:"originNote"`
	OriginContactName       string `json:"originContactName"`
	OriginContactPhone      string `json:"originContactPhone"`
	OriginLatLong           string `json:"originLatLong"`
	OriginAddress           string `json:"originAddress"`
	DestinationName         string `json:"destinationName"`
	DestinationNote         string `json:"destinationNote"`
	DestinationContactName  string `json:"destinationContactName"`
	DestinationContactPhone string `json:"destinationContactPhone"`
	DestinationLatLong      string `json:"destinationLatLong"`
	DestinationAddress      string `json:"destinationAddress"`
	Item                    string `json:"item"`
	StoreOrderId            string `json:"storeOrderId"`
}

type Response struct {
	Id             string `json:"id"`
	OrderNo        string `json:"orderNo"`
	Status         string `json:"status"`
	BookingType    string `json:"bookingType"`
	StoreOrderId   string `json:"storeOrderId"`
	ErrorMessage   string `json:"errorMessage"`
	Prebook        bool   `json:"prebook"`
	PrebookMessage string `json:"prebookMessage"`
}

type GoSendSvc struct {
	ClientId   string `json:"clientId"`
	PassKey    string `json:"passKey"`
	BookingApi string `json:"bookingApi"`
	//Authorization string `json:"authorization"`
}

// Booking 预约下单
func (svc *GoSendSvc) Booking(route Route) (Response, error) {
	// url := "https://integration-kilat-api.gojekapi.com/gokilat/v10/booking" // 测试API

	headers := map[string]string{
		"Content-Type": "application/json",
		"Accept":       "application/json",
		"Client-ID":    svc.ClientId,
		"Pass-Key":     svc.PassKey,
	}

	var data = Request{
		PaymentType:        3,
		CollectionLocation: "pickup",
		ShipmentMethod:     "SameDay",
		Routes:             []Route{route},
	}

	req, err := json.Marshal(data)
	if err != nil {
		slog.Error(err.Error())
		return Response{}, errors.New("booking failed")
	}

	res, err := utils.HttpPost(svc.BookingApi, headers, req)
	if err != nil {
		slog.Error(err.Error())
		return Response{}, err
	}
	if res.Status != http.StatusCreated {
		slog.Error(string(res.Body))
		return Response{}, errors.New(res.Header.Get("Error-Message"))
	}
	var response Response
	err = json.Unmarshal(res.Body, &response)
	if err != nil {
		slog.Error(err.Error())
		return Response{}, err
	}
	if len(response.ErrorMessage) > 0 {
		return Response{}, errors.New(response.ErrorMessage)
	}

	return response, nil
}

// Cancel 取消预约
// When the booking status before Enroute_Pickup status 仅能取消物流状态为上门取件前的订单
func (svc *GoSendSvc) Cancel(number string) error {
	url := svc.BookingApi + "/cancel"
	headers := map[string]string{
		"Content-Type": "application/json",
		"Accept":       "application/json",
		"Client-ID":    svc.ClientId,
		"Pass-Key":     svc.PassKey,
	}

	var data = map[string]any{
		"orderNo": number,
	}

	req, err := json.Marshal(data)
	if err != nil {
		slog.Error(err.Error())
		return errors.New("cancel delivery failed, err:" + err.Error())
	}

	res, err := utils.HttpPut(url, headers, req)
	if err != nil {
		slog.Error(err.Error())
		if res.Status > 0 {
			errMsg := res.Header.Get("Error-Message")
			slog.Error("cancel delivery failed, err: ", errMsg)
			return errors.New("cancel delivery failed, err: " + errMsg)
		}
		return err
	}
	return nil
}
